﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using Casamiel.API.Application;
using Casamiel.API.Application.Commands;
using Casamiel.API.Application.Models.Store;
using Casamiel.API.Application.Services;
using Casamiel.Application;
using Casamiel.Common;
using Casamiel.Common.Extensions;
using Casamiel.Domain.Entity;
using Casamiel.Domain.Request;
using Casamiel.Domain.Request.IC;
using MediatR;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NLog;

// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860

namespace Casamiel.API.Controllers.V2
{
    /// <summary>
    /// 
    /// </summary>
    [Produces("application/json")]
    [ApiVersion("2.0")]
    [Route("api/v{api-version:apiVersion}/[controller]")]
    [ApiController]
    public class JDController : ControllerBase
    {
        private readonly NLog.ILogger logger = LogManager.GetLogger("OrderService");
        //private readonly ICacheService _cacheService;
        private readonly IIcApiService _icApiService;
        private readonly IStoreApiService _storeApiService;
        private readonly INoticeService _notice;
        private readonly IOrderService _order;
        private readonly ICasaMielSession _session;
        private readonly string _apitoken;
        private readonly IMediator _mediator;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="settings"></param>
        /// <param name="iicApiService"></param>
        /// <param name="storeApiService"></param>
        /// <param name="session"></param>
		/// <param name="mediator"></param>
        /// <param name="notice"></param>
        /// <param name="order"></param>
        public JDController(IOptionsSnapshot<CasamielSettings> settings, IIcApiService iicApiService, IStoreApiService storeApiService,
           ICasaMielSession session, IMediator mediator, INoticeService notice, IOrderService order)
        {
            if (settings == null) {
                throw new ArgumentNullException(nameof(settings));
            }

            _apitoken = settings.Value.ApiToken;
            _icApiService = iicApiService;
            _storeApiService = storeApiService;
            _session = session;
            _mediator = mediator;
            _notice = notice;
            _order = order;
        }
        /// <summary>
        /// Gets the order.
        /// </summary>
        /// <returns>The order.</returns>
        /// <param name="ordercode">Ordercode.</param>
        [HttpGet]
        [Route("[Action]")]
        public async Task<IActionResult> GetOrder(string ordercode)
        {
            var orderentity = await _order.GetByOrderCodeAsync<ICasaMielSession>(ordercode).ConfigureAwait(false);
            return Ok(orderentity);
        }
        /// <summary>
        /// Checks the CO rder.
        /// </summary>
        /// <returns>The CO rder.</returns>
        /// <param name="data">Data.</param>
        /// <param name="token">Token.</param>
        [HttpPost]
        [Route("[Action]")]
        public async Task<IActionResult> CheckOrder([FromBody]  Order_AddJDReq data, [FromHeader(Name = "u-token")] string token)
        {
            if (token != _apitoken) {
                return Ok(new { code = 99999, msg = "token无效" });
            }
            var orderentity = await _order.GetByOrderCodeAsync<ICasaMielSession>(data.OrderId.ToString(CultureInfo.CurrentCulture)).ConfigureAwait(false);
            if (orderentity == null) {
                return Ok(new { code = 9999, msg = "" });
            }
            return Ok(new { code = 0, msg = "" });
        }
        /// <summary>
        /// JD到家下单
        /// </summary>
        /// <param name="data"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("[Action]")]
        public async Task<IActionResult> AddOrder([FromBody]  Order_AddJDReq data, [FromHeader(Name = "u-token")] string token)
        {
            if (data == null) {
                throw new ArgumentNullException(nameof(data));
            }

            logger.Trace($"AddJDOrder:{JsonConvert.SerializeObject(data)}");
            string a = "424009,424010,423986,419685,424151,423986";
            List<string> blacklist = new List<string>();
            blacklist = a.Split(',').ToList();
            logger.Trace($"JDAddOrder:{JsonConvert.SerializeObject(data)}");
            if (token != _apitoken) {
                Response.StatusCode = (int)HttpStatusCode.Unauthorized;
                return Ok(new { code = 99999, msg = "token无效" });
            }
            var shopid = data.DeliveryStationNoIsv.ToInt32(0);

            var Orderoriginprice = 0m;
            var ptprice = new IcPriceReq { Shopid = shopid, Product = new List<ProductItemReq>() };

            foreach (var item in data.Product) {
                ptprice.Product.Add(new ProductItemReq { Pid = item.SkuIdIsv, Count = 1 });
            }
            var pzmodel = await _icApiService.ProductStockQuery(ptprice).ConfigureAwait(false);
            if (pzmodel.product.Count > 0) {
                foreach (var item in data.Product) {
                    var iteminfo = pzmodel.product.Find(cw => cw.pid == item.SkuIdIsv);
                    if (iteminfo != null) {
                        var total = iteminfo.originprice * item.SkuCount;
                        Orderoriginprice += total;
                        if (blacklist.Contains(item.SkuIdIsv)) {
                            continue;
                        }
                        //库存不足
                        if (iteminfo.count < item.SkuCount) {
                            HttpClient _client = new HttpClient();
                            //                            orderId String 是 100001016163464 订单号
                            //isAgreed Boolean 是 true 操作类型 true 接单 false不接单 
                            //operator String 是 test 操作人
                            var orderAcceptOperate = "{ \"orderId\":" + data.OrderId + ",\"isAgreed\":false,\"operator\":\"可莎密兒\"}";
                            var result = await _storeApiService.JDorderAcceptOperate(orderAcceptOperate).ConfigureAwait(false);
                            logger.Trace(result);
                            var da = JsonConvert.DeserializeObject<JObject>(result);
                            if (da["code"].ToString() == "0") {
                                var re = JsonConvert.DeserializeObject<JObject>(da["data"].ToString());
                                if (re["code"].ToString() == "0") {
                                    return Ok(new { code = 0, msg = "商品库存不足！" });
                                }
                            }
                            return Ok(new { code = 999, msg = "商品库存不足" });
                        }
                    } else {
                        return Ok(new { code = 999, msg = "商品下架" });
                    }
                }
            } else {

                return Ok(new { code = 999, msg = "商品下架" });
            }
            var orderentity = await _order.GetByOrderCodeAsync<ICasaMielSession>(data.OrderId.ToString(CultureInfo.CurrentCulture)).ConfigureAwait(false);
            if (orderentity != null) {
                return Ok(new { code = 0, msg = "订单已存！" });
            }
            if (data.OrderId == 814909642000241 || data.OrderId == 814911544000541) {
                return Ok(new { code = 0, msg = "订单已存！" });
            }
            var ictradeNO = "";
            var billNO = "";
            var discu = data.OrderDiscountMoney.ToDecimal(0) / 100;

            var icdto = new IcconsumeReq {
                Phoneno = data.BuyerMobile, Cardno = "", Rebate = discu.ToString(CultureInfo.CurrentCulture).ToDouble(0), Shopid = shopid,
                Pickuptime = data.OrderPreStartDeliveryTime.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.CurrentCulture)
            };
            icdto.Product = new List<IcconsumeReq.IcconsumeProductItem>();
            foreach (var item in data.Product) {
                icdto.Product.Add(new IcconsumeReq.IcconsumeProductItem { Pid = item.SkuIdIsv, Count = item.SkuCount, Pname = "" });
            }
            var icentity = await _icApiService.ThirdOrder(icdto).ConfigureAwait(false);
            logger.Trace($"thirdorder:req:{JsonConvert.SerializeObject(icdto)},rsp:{JsonConvert.SerializeObject(ictradeNO)}");
            if (icentity.code == 0) {
                var jobject = JsonConvert.DeserializeObject<JObject>(icentity.content);
                ictradeNO = jobject["tradeno"].ToString();
                billNO = jobject["billno"].ToString();
                data.IcTradeNo = ictradeNO;
                data.BillNo = billNO;
            } else {
                return Ok(icentity);
            }

            try {
                var result = await _storeApiService.AddJdOrder(data).ConfigureAwait(false);
                logger.Trace($"AddJdOrder:{result}");
                var dynamicdata = JsonConvert.DeserializeObject<JObject>(result);
                if (dynamicdata["ResultNo"].ToString() == "00000000") {
                    var pay = new IcConsumepayReq {
                        Phoneno = data.BuyerMobile,
                        Shopid = shopid,
                        Tradeno = ictradeNO,
                        Createinvoice = true
                    };
                    pay.Paycontent = new List<IcConsumepayReq.PaycontentItem>
                    {
                        new IcConsumepayReq.PaycontentItem
                        {
                            Paytype = "9",
                            Paymoney = (data.OrderBuyerPayableMoney).ToDouble(0) / 100,
                            Paytradeno = $"{data.OrderId}C{DateTime.Now.ToString("yyMMddHHmmssffff",CultureInfo.CurrentCulture)}"
                        }
                    };
                    pay.Payfee = new List<IcConsumepayReq.PayfeeItem>();
                    if (data.OrderFreightMoney > 0) {
                        pay.Payfee.Add(new IcConsumepayReq.PayfeeItem { Feetype = "1", Fee = (data.OrderFreightMoney).ToDouble(0) / 100, Description = "配送费" });//配送费
                    }
                    if (data.PackagingMoney > 0) {
                        pay.Payfee.Add(new IcConsumepayReq.PayfeeItem { Feetype = "2", Fee = data.PackagingMoney.ToDouble(0) / 100, Description = "包装费" });//包装费
                    }

                    if (data.PlatformPointsDeductionMoney > 0) {
                        pay.Payfee.Add(new IcConsumepayReq.PayfeeItem { Feetype = "3", Fee = data.PlatformPointsDeductionMoney.ToDouble(0) / 100, Description = "第三方平台积分抵扣金额" });//第三方平台抵扣金额 
                    }
                    if (data.OrderDiscountMoney > 0) {
                        pay.Payfee.Add(new IcConsumepayReq.PayfeeItem { Feetype = "3", Fee = data.OrderDiscountMoney.ToDouble(0) / 100, Description = "优惠券" });//第三方平台抵金额 
                    }
                    logger.Trace($"icconsumepay:{JsonConvert.SerializeObject(pay)}");
                    var zmodel = await _icApiService.Icconsumepay(pay).ConfigureAwait(false);
                    logger.Trace($"icconsumepayResult:{JsonConvert.SerializeObject(zmodel)}");
                    if (zmodel.code == 0) {
                        var order = await _order.GetByOrderCodeAsync<ICasaMielSession>(data.OrderId.ToString(CultureInfo.CurrentCulture)).ConfigureAwait(false);
                        using (var uow = _session.UnitOfWork(IsolationLevel.Serializable)) {
                            var noticEntity = new NoticeBaseEntity() {
                                RemindTime = DateTime.Now.AddMinutes(-3),
                                CreateTime = DateTime.Now,
                                RelationId = order.OrderBaseId,
                                StoreId = order.StoreId,
                                NoticeType = 0
                            };
                            await _notice.AddAsync(noticEntity, uow).ConfigureAwait(false);
                        }
                        var orderAcceptOperate = "{ \"orderId\":" + data.OrderId + ",\"isAgreed\":true,\"operator\":\"可莎密兒\"}";
                        var result1 = await _storeApiService.JDorderAcceptOperate(orderAcceptOperate).ConfigureAwait(false);
                        logger.Trace($"接单：{result1}");
                        return Ok(new { code = 0, msg = "" });
                    } else {
                        var backreq = new ThirdOrderBackReq { Tradeno = ictradeNO };
                        var d = await _icApiService.ThirdOrderBack(backreq).ConfigureAwait(false);
                        if (d.code == 0) {
                            var r = await _storeApiService.OrderDelete(data.OrderId.ToString(CultureInfo.CurrentCulture)).ConfigureAwait(false);
                            logger.Trace($"OrderDelete:{r}");
                        }
                        return Ok(d);
                    }
                } else {
                    var backreq = new ThirdOrderBackReq { Tradeno = ictradeNO };
                    var d = await _icApiService.ThirdOrderBack(backreq).ConfigureAwait(false);
                    return Ok(new { code = 9999, msg = dynamicdata["ResultRemark"].ToString() });
                }
            } catch (HttpRequestException ex) {
                logger.Error($"AddJdOrder:{ex.StackTrace}");
                var d = await _icApiService.ThirdOrderBack(new ThirdOrderBackReq { Tradeno = ictradeNO }).ConfigureAwait(false);
                if (d.code == 0) {
                    var r = await _storeApiService.OrderDelete(data.OrderId.ToString()).ConfigureAwait(false);
                    logger.Trace($"OrderDelete:{r}");
                }
                return Ok(new { code = 9999, msg = ex.Message });
            }
        }
        /// <summary>
        /// S the specified data and token.
        /// </summary>
        /// <returns>The s.</returns>
        /// <param name="data">Data.</param>
        /// <param name="token">Token.</param>
        /// <remarks>{"orderId":"","orderstatus":"","remark":""}</remarks>
        [HttpPost]
        [Route("[Action]")]
        public async Task<IActionResult> ChangeOrderStaus([FromBody]  ChangeOrderStausReq data, [FromHeader(Name = "u-token")] string token)
        {
            logger.Trace($"ChangeOrderStaus:{JsonConvert.SerializeObject(data)}");

            if (token != _apitoken) {
                Response.StatusCode = (int)HttpStatusCode.Unauthorized;
                return Ok(new { code = 99999, msg = "token无效" });
            }
            var entity = await _order.GetByOrderCodeAsync<ICasaMielSession>(data.orderId).ConfigureAwait(false);
            if (entity == null) {
                return Ok(new { code = 9999, msg = "订单不存在" });
            }
            //orderStatus == "20020"  用户取消
            if (data.orderstatus == "20020") {
                var cancelCommand = new CancelOrderCommand(data.orderId, 3, "", "");
                var result1 = await _mediator.Send(cancelCommand).ConfigureAwait(false);
                if (result1.code > 0) {
                    return Ok(result1);
                }
                //var d = await _icApiService.icconsumeback(new IcConsumeBackDto { phoneno = entity.ContactPhone, tradeno = entity.IcTradeNO });
                // if (d.code == 0 || d.code == 205)
                // {
                //     JObject obj = JsonConvert.DeserializeObject<JObject>(d.content);
                //     logger.Trace($"icconsumeback:{d.content}");

                //     logger.Trace($"OrderCode:{entity.OrderCode},tradeno_origin:{obj["tradeno_origin"].ToString()},tradeno:{obj["tradeno"].ToString()},");
                //     var billno = obj["tradeno"].ToString();

                //       entity.ResBillNo = billno;
                //          using (var uow = _session.UnitOfWork(IsolationLevel.Serializable))
                //         {
                //            var s = await _storeService.OrderBaseUPdateAsync(entity, uow);
                //         }
                //     }
                // else
                // {
                //     return Ok(d);
                // }
            }
            //orderStatus == "33060"  订单妥投 完成
            if (data.orderstatus == "33060") {
                var commandPickup = new ThirdOrderPickupCommand(data.orderId, 3);
                var pickupResult = await _mediator.Send(commandPickup).ConfigureAwait(false);
                if (pickupResult.code > 0) {
                    return Ok(pickupResult);
                }
                //            IcorderpickupDto dto = new IcorderpickupDto()
                //            {
                //                phoneno =entity.ContactPhone,
                //                tradeno = entity.IcTradeNO
                //            };
                //            var re = await _icApiService.icorderpickup(dto);
                //            if (re.code == 0)
                //            {
                //                var jobject = JsonConvert.DeserializeObject<JObject>(re.content);
                //                var billno = jobject["billno"].ToString();
                //	using (var uow = _session.UnitOfWork(IsolationLevel.Serializable))
                //	{
                //		entity.ResBillNo = billno;
                //		//entity.OrderStatus = 8;
                //		var s = await _storeService.OrderBaseUPdateAsync(entity, uow);
                //		//var take = await _storeService.UpdateOrderTakeStatus(entity.OrderBaseId, -1, billno, uow);
                //		//var dis = await _storeService.UpdateOrderDiscountStatus(entity.OrderBaseId, 1, uow);
                //	}
                //	//return Ok(new { code = 0, billno = billno });
                //}
                //else
                //{
                //	return Ok(re);
                //}
            }
            var result = await _storeApiService.JDChangeStaus(data).ConfigureAwait(false);

            var dynamicdata = JsonConvert.DeserializeObject<JObject>(result);
            if (dynamicdata["ResultNo"].ToString() == "00000000") {
                return Ok(new { code = 0, msg = "" });
            }
            return Ok(new { code = 9999, msg = dynamicdata["ResultRemark"].ToString() });
        }
    }
}